package scales;

import midi.IntervalOperations;
import midi.MidiPhrase;
import midi.IntervalOperations.interval;
import midi.patterns.Intervalable;
import midi.patterns.Phrasable;

public class MidiPhraser implements Phrasable{
	private interval intervals[];
	private long lengths[];
	private int velocities[];
	private int rootNoteNumber;
	private int noteNumbers[];
	
	public MidiPhraser(Intervalable intervalable, int rootNoteNumber){
		this(intervalable.getIntervals(), rootNoteNumber);
	}
	
	public MidiPhraser(interval[] intervals, int rootNoteNumber){
		this(intervals, 100, 4, rootNoteNumber);
	}
	
	public MidiPhraser(interval[] intervals, int velocity, long length, int rootNoteNumber){
		this.intervals = intervals;
		int numNotes = intervals.length;
		lengths = new long[numNotes];
		velocities = new int[numNotes];
		this.rootNoteNumber = rootNoteNumber;
		noteNumbers = new int[numNotes];
		
		setLength(length);
		setVelocity(velocity);
		
		updateNoteNumbers();
	}
	
	public MidiPhraser(interval[] intervals, int[] velocities, long[] lengths, int rootNoteNumber){
		this.intervals = intervals;
		this.velocities = velocities;
		this.lengths = lengths;
		this.rootNoteNumber = rootNoteNumber;
		this.noteNumbers = new int[intervals.length];
		
		updateNoteNumbers();
	}
	
	private void updateNoteNumbers(){
		for (int i = 0; i < intervals.length; i++){
			noteNumbers[i] = IntervalOperations.raise(rootNoteNumber, intervals[i]);
		}
	}
	
	public int getRootNoteNumber(){
		return rootNoteNumber;
	}
	
	public void setRootNoteNumber(int noteNumber){
		rootNoteNumber = noteNumber;
		updateNoteNumbers();
	}
	
	
	public interval[] getIntervals(){
		return intervals;
	}
	
	public void setIntervals(interval[] intervals){
		int prevLength = this.intervals.length;
		this.intervals = intervals;
		
		if (prevLength < intervals.length){
			extendArrays(prevLength - 1);
		}
		updateNoteNumbers();
	}
	
	public void setIntervals(Intervalable intervalable){
		setIntervals(intervalable.getIntervals());
	}
	
	public long[] getLengths(){
		return lengths;
	}
	
	public void setLengths(long lengths[]){
		this.lengths = lengths;
	}
	
	public void setLength(long length){
		for (int i = 0; i < intervals.length; i++){
			lengths[i] = length;
		}
	}
	
	private void extendArrays(int firstIndex){
		int source = firstIndex - 1;
		for (int i = firstIndex; i < intervals.length; i++){
			lengths[i] = lengths[source];
			velocities[i] = velocities[source];
		}
	}
	
	
	public int[] getVelocities(){
		return velocities;
	}
	
	public void setVelocities(int velocities[]){
		this.velocities = velocities;
	}
	
	public void setVelocity(int velocity){
		for (int i = 0; i < intervals.length; i++){
			velocities[i] = velocity;
		}
	}
	

	@Override
	public MidiPhrase toMidiPhrase() {
		return new MidiPhrase(noteNumbers, velocities, lengths);
	}
}
